﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CLEX.Service.DataContracts;

namespace CLEX.Client.Metro
{
    public class LatticeState
    {
        private readonly HashSet<string> latticeColumns = new HashSet<string>();
        private readonly HashSet<string> groupByColumns = new HashSet<string>();
        private readonly HashSet<AggregateData> aggregates = new HashSet<AggregateData>();

        public event Action LatticeColumnsChanged;
        public event Action GroupByColumnsChanged;
        public event Action<AggregateData> AggregateAdded;
        public event Action<AggregateData> AggregateRemoved;

        public IEnumerable<string> LatticeColumns
        {
            get { return new List<string>(latticeColumns); }
            set
            {
                this.latticeColumns.Clear();
                this.latticeColumns.UnionWith(value);
                RaiseLatticeColumnsChanged();
            }
        }

        public IEnumerable<string> GroupByColumns
        {
            get { return new List<string>(groupByColumns); }
            set
            {
                this.groupByColumns.Clear();
                this.groupByColumns.UnionWith(value);
                RaiseGroupByColumnsChanged();
            }
        }

        public IEnumerable<AggregateData> Aggregates
        {
            get { return new List<AggregateData>(aggregates); }
        }

        public bool AddAggregate(AggregateData aggregate)
        {
            if (aggregates.Add(aggregate))
            {
                RaiseAggregateAdded(aggregate);
                return true;
            }
            return false;
        }

        public bool RemoveAggregate(AggregateData aggregate)
        {
            if (aggregates.Remove(aggregate))
            {
                RaiseAggregateRemoved(aggregate);
                return true;
            }
            return false;
        }

        private void RaiseAggregateRemoved(AggregateData aggregate)
        {
            var handler = AggregateRemoved;
            if (handler != null)
            {
                handler.Invoke(aggregate);
            }
        }

        private void RaiseAggregateAdded(AggregateData aggregate)
        {
            var handler = AggregateAdded;
            if (handler != null)
            {
                handler.Invoke(aggregate);
            }
        }

        private void RaiseLatticeColumnsChanged()
        {
            var handler = LatticeColumnsChanged;
            if (handler != null)
            {
                handler.Invoke();
            }
        }

        private void RaiseGroupByColumnsChanged()
        {
            var handler = GroupByColumnsChanged;
            if (handler != null)
            {
                handler.Invoke();
            }
        }
    }
}
